﻿using System.Net;
using System.Text;

namespace BlazorAdmin.Tcp.Protocol
{
    /// <summary>
    /// 文件转换类型枚举
    /// </summary>
    public enum TextEncoder
    {
        NONE, UTF8, ASCII
    }

    /// <summary>
    /// 指示数据类型
    /// </summary>
    [AttributeUsage(AttributeTargets.All)]
    public class DataTypeAttribute : Attribute
    {
        /// <summary>
        /// 标示数据类型
        /// </summary>
        public Type? DataType { get; set; }

        /// <summary>
        /// 数据长度
        /// </summary>
        public int DataLength { get; set; }

        /// <summary>
        /// 数据编码
        /// </summary>
        public TextEncoder Encoder { get; set; } = TextEncoder.NONE;

        /// <summary>
        /// 获取数据转换值
        /// </summary>
        /// <param name="buffer">转换缓存</param>
        /// <param name="start">起始位置</param>
        /// <returns></returns>
        public (byte, int) GetByte(byte[] buffer, int start)
        {
            if (null == DataType || typeof(byte) != DataType)
                return default;
            return (buffer[start], 1);
        }

        /// <summary>
        /// 获取数据转换值
        /// </summary>
        /// <param name="buffer">转换缓存</param>
        /// <param name="start">起始位置</param>
        /// <returns></returns>
        public (int, int) GetInt(byte[] buffer, int start)
        {
            if (null == DataType || typeof(int) != DataType || DataLength == 0 || DataLength < sizeof(int))
                return default;
            return (buffer.ToInt(start, DataLength), DataLength);
        }

        /// <summary>
        /// 获取数据转换值
        /// </summary>
        /// <param name="buffer">转换缓存</param>
        /// <param name="start">起始位置</param>
        /// <returns></returns>
        public (string, int) GetString(byte[] buffer, int start)
        {
            if (TextEncoder.NONE == Encoder)
                return (string.Empty, 0);

            Encoding encoding = TextEncoder.UTF8 == Encoder ? Encoding.UTF8 : Encoding.ASCII;
            int len = DataLength < 1 ? buffer.Length - start : DataLength;

            string value = encoding.GetString(buffer, start, len);
            return (value, DataLength < 1 ? len + 1 : DataLength);
        }

        /// <summary>
        /// 获取数据转换值
        /// </summary>
        /// <param name="buffer">转换缓存</param>
        /// <param name="start">起始位置</param>
        /// <returns></returns>
        public (IPAddress, int) GetAddress(byte[] buffer, int start)
        {
            IPAddress address = IPAddress.Any;
            if (null == DataType || typeof(IPAddress) != DataType)
                return (address, default);
            string ip = $"{buffer[start]}.{buffer[start + 1]}.{buffer[start + 2]}.{buffer[start + 3]}";
            return (IPAddress.TryParse(ip, out IPAddress? ipAddr) ? ipAddr : address, 4);
        }
    }
}
